package pl.edu.agh.mgr.hotel.main;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.Random;
import java.util.TreeSet;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import pl.edu.agh.mgr.hotel.routing.algorithms.simple.P2P;
import pl.edu.agh.mgr.hotel.routing.algorithms.simple.P2PType;
import pl.edu.agh.mgr.hotel.ws.client.DataRequest;
import pl.edu.agh.mgr.hotel.ws.client.DataResponse;
import pl.edu.agh.mgr.hotel.ws.client.Query;
import pl.edu.agh.mgr.hotel.ws.client.ServiceDescription;
import pl.edu.agh.mgr.hotel.ws.configuration.WSUtil;

public class ClientThread implements Runnable {

	private final String name;
	private final String wsName;
	private Logger log;
	private static final List<String> hotelNames = new ArrayList<String>();
	private static final List<String> cities = new ArrayList<String>();

	static {
		// hotelNames.add("H0");
		 hotelNames.add("H1");
		 hotelNames.add("H2");
		 hotelNames.add("H3");
		 hotelNames.add("H4");
		 hotelNames.add("H5");
		 hotelNames.add("H6");
		 hotelNames.add("H7");
		 hotelNames.add("H8");
		 hotelNames.add("H9");
		 hotelNames.add("H10");
		 hotelNames.add("H11");
		// hotelNames.add("H12");
		// hotelNames.add("H13");
		// hotelNames.add("H14");
		// hotelNames.add("H15");
		// hotelNames.add("H16");
		// hotelNames.add("H17");
		// hotelNames.add("H18");
		// hotelNames.add("H19");
		// hotelNames.add("H20");
		// hotelNames.add("H21");
		// hotelNames.add("H22");
		// hotelNames.add("H23");
		// hotelNames.add("H24");
		// hotelNames.add("H25");
		// hotelNames.add("H26");
		// hotelNames.add("H27");
		// hotelNames.add("H28");
		// hotelNames.add("H29");
		// hotelNames.add("H30");

		cities.add("C1");
		cities.add("C2");
		cities.add("C3");
		cities.add("C4");
		cities.add("C5");
//		cities.add("C69");
	}

	public ClientThread(String name, String wsName) {
		PropertyConfigurator.configure("log4j.properties");
		log = Logger.getLogger(name);
		this.name = name;
		this.wsName = wsName;
	}

	@Override
	public void run() {
		P2P p2p = new P2P(wsName);

		// FIXME: dla hopow malejaco
		for (int i = 0; i < 40; i++) {
			List<DataResponse> dataResponseList = p2p.getResults(
					getDataRequest(), P2PType.BFS);

			logSearchingResult(dataResponseList);

			try {
				Thread.sleep(3000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}

		// // FIXME: dla hopow malejaco
		// for (int i = 0; i < 40; i++) {
		// int nr = i % hotelNames.size();
		//
		// if (!hotelNames.get(nr).equals(name)) {
		// List<DataResponse> dataResponseList = p2p.getResults(
		// getDataRequest(hotelNames.get(nr)), P2PType.BFS);
		//
		// logSearchingResult(dataResponseList);
		// }
		// try {
		// Thread.sleep(3000);
		// } catch (InterruptedException e) {
		// e.printStackTrace();
		// }
		// }
		//

		// for (int i = 0; i < 40; i++) {
		// int nr = i % cities.size();
		//
		// List<DataResponse> dataResponseList = p2p.getResults(
		// getDataRequest(cities.get(nr)), P2PType.BFS);
		//
		// logSearchingResult(dataResponseList);
		//
		// try {
		// Thread.sleep(3000);
		// } catch (InterruptedException e) {
		// e.printStackTrace();
		// }
		// }

	}

	// private String getRandomHotelName(String hotelName) {
	// String newHotelName = hotelNames.get(new Random().nextInt(hotelNames
	// .size()));
	// while (hotelName == newHotelName) {
	// newHotelName = hotelNames.get(new Random().nextInt(hotelNames
	// .size()));
	// }
	//
	// return newHotelName;
	// }

	private String getRandomCity() {
		return cities.get(new Random().nextInt(cities.size()));
	}

	private DataRequest getDataRequest() {
		List<Query> queries = new ArrayList<Query>();
		String searchedItem = getRandomCity();

		log.info("Searching for " + searchedItem + "...");

					
//		Query query = null;
//		for (ServiceDescription peer : WSUtil.getPeersCache(wsName).getPeers()) {
//			
//			if (peer.getLastModifiedDateAsDate() == null) {
//				query = new Query(peer.getName() + "ChangeDate",null);
//			} else {
//				query = new Query(peer.getName() + "ChangeDate",
//					Long.toString(peer.getLastModifiedDateAsDate().getTime()));
//			}
//			queries.add(query);			
//		}
		
		// data levels
		for (ServiceDescription peer : WSUtil.getPeersCache(wsName).getPeers()) {
			Query query = new Query(peer.getName() + "DataLevel",
					Integer.toString(peer.getDataLevel()));
			queries.add(query);
		}

		// FIXME : hotel name za miast city
		queries.add(new Query("city", searchedItem));
		// queries.add(new Query("name", searchHotelName));
		return new DataRequest(name, queries);
	}

	private void logSearchingResult(List<DataResponse> dataResponseList) {

		if (!dataResponseList.isEmpty())
			for (DataResponse dataResponse : dataResponseList)
				log.info(dataResponse.getName());
		else
			log.info("No match found");

		log.info("End searching.");
	}

}
